package com.jfinal.server;

import java.io.IOException;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.Logger;

import com.jfinal.aop.Invocation;


/**
 * 异常切面拦截<br/>
 */
public class ExceptionAdvisor{

	/**
	 * 
	 */
	private static final Logger log = Logger.getLogger(ExceptionAdvisor.class);
	
	private static final ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<SimpleDateFormat>() {
		protected SimpleDateFormat initialValue() {
			return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		}
	};
	
	public static void getExceptionInfo(Exception ex,Invocation inv){
		log.error(inv.getController().getClass().getName());
		log.error(inv.getMethodName());
		
		StringBuilder sb = new StringBuilder("\nController exception ---------- ").append(sdf.get().format(new Date())).append(" ----------\n");
		sb.append("Controller  :  ").append(inv.getController().getClass().getName()).append(".(").append(inv.getController().getClass().getSimpleName()).append(".java:1)");
		sb.append("\nMethod     :  ").append(inv.getMethodName());
		sb.append("\nerrorMsg     :  ").append(getExceptionMsg(ex));
		sb.append("\n\t\t      ").append(ex);
		for(StackTraceElement e:ex.getStackTrace()){
			sb.append("\n\t\t      ").append(e.getClassName()+".("+e.getClass().getSimpleName()+".java:"+e.getLineNumber()+")");
		}
		sb.append("\n----------------------------------------------------------------------------");
		System.out.println(sb);
	}
	
	public static String getExceptionMsg(Exception ex){
		String errorStr = "程序内部错误，操作失败!";
		if (ex.getClass().toString().equals(NullPointerException.class.toString())) { 
			log.error("调用了未经初始化的对象或者是不存在的对象!");    
			errorStr = "调用了未经初始化的对象或者是不存在的对象!";
		} else if (ex.getClass().equals(IOException.class)) {  
			log.error("IO操作异常!");   
			errorStr = "IO操作异常!";
		} else if (ex.getClass().equals(ClassNotFoundException.class)) {  
			log.error("指定的类不存在!"); 
			errorStr = "指定的类不存在!";
		} else if (ex.getClass().equals(ArithmeticException.class)) {  
			log.error("数学运算异常!");
			errorStr = "数学运算异常!";
		} else if (ex.getClass().equals(ArrayIndexOutOfBoundsException.class) || ex.getClass().equals(IndexOutOfBoundsException.class)) {  
			log.error("数组下标越界!");    
			errorStr = "数组下标越界!";
		} else if (ex.getClass().equals(IllegalArgumentException.class)) {  
			log.error("方法的参数错误!");   
			errorStr = "方法的参数错误!";
		} else if (ex.getClass().equals(ClassCastException.class)) {  
			log.error("类型强制转换错误!");   
			errorStr = "类型强制转换错误!";
		} else if (ex.getClass().equals(SecurityException.class)) {   
			log.error("违背安全原则异常!");   
			errorStr = "违背安全原则异常!";
		} else if (ex.getClass().equals(SQLException.class)) {  
			log.error("操作数据库异常!");  
			errorStr = "操作数据库异常!";
		} else if (ex.getClass().equals(NoSuchMethodError.class)) { 
			log.error("方法未找到异常!");    
			errorStr = "方法未找到异常!";
		} else if (ex.getClass().equals(InternalError.class)) { 
			log.error("Java虚拟机发生了内部错误");    
			errorStr = "Java虚拟机发生了内部错误";
		}else if(ex.getLocalizedMessage().indexOf("MySQLSyntaxErrorException") > -1){
			log.error("Sql语句有误");
			log.error(ex.getLocalizedMessage());
			errorStr = "Sql语句有误";
		}else {
			log.error("程序内部错误，操作失败!");  
		}
		
		return errorStr;
	}
	
	/**
	 *service抛出异常
	 */
	public static void serviceExceptionMsg (Exception ex,Invocation inv){
		log.error(inv.getTarget().getClass().getName());
		log.error(inv.getMethodName());
		log.error("异常语句:"+ex.getLocalizedMessage());
		
		StringBuilder sb = new StringBuilder("\nService exception ---------- ").append(sdf.get().format(new Date())).append(" ----------\n");
		sb.append("Service  :  ").append(inv.getTarget().getClass().getName()).append(".(").append(inv.getTarget().getClass().getSimpleName()).append(".java:1)");
		sb.append("\nMethod     :  ").append(inv.getMethodName());
		sb.append("\nerrorMsg     :  ").append(getExceptionMsg(ex));
		sb.append("\n\t\t      ").append(ex);
		sb.append("\n----------------------------------------------------------------------------");
		System.out.println(sb);
	}

}
